(function($) {
	window.$EliteChart = {
        
		version: '2019-6-12 17:33:53',
    	
    	/**
    	 * 所有项目EliteChart的实例
    	 */
    	instance: {},
    	
    	/**
		 * 获取当前项目的单例实例
		 * 
		 * @method getInstance
		 * @param project {object} 项目对象
		 * @return {object} EliteChart的实例对象
		 */
    	getInstance: function(project) {
    		if(window.filesaver != true){
    			require(['./js/lib/filesaver' + $E.jsv], function() {
    				window.filesaver = true;
				});
    		}
			if (! project) {
				$F.err('elite.chart - getInstance', 'project is empty: ', project);
			}
			if (!this.instance[project.id]) {
				this.instance[project.id] = new EliteChart(project);
			}
			return this.instance[project.id];
		},
        
		/**
		 * resize在某个容器里的所有图表
		 * 
		 * @method resizeChartsInContainer
		 * @param container {$obj} 容器
		 */
		resizeChartsInContainer: function(container) {
			$.each($('div[data-highcharts-chart]', container), function(index, chartContainer) {
				$(chartContainer).highcharts() && $(chartContainer).highcharts().reflow();
			});
			$.each($('div[_echarts_instance_]', container), function(index, chartContainer) {
				echarts.getInstanceByDom(chartContainer) &&  echarts.getInstanceByDom(chartContainer).resize();
			});
		},
        
		/**
		 * 图表实例销毁
		 * 
		 * @method destroy
		 * @param container {$obj} 容器
		 */
		destroy: function(container){
			// 销毁resize方法
			container.parent()[0].__resizeListeners__ = [];
			
			if(container.highcharts()){
				container.highcharts().destroy();
			}
			if (echarts.getInstanceByDom(container[0])) {
				echarts.getInstanceByDom(container[0]).dispose();
			}
		},

		/**
		 * 图表数据清空
		 * 
		 * @method clear
		 * @param container {$obj} 容器
		 */
		clear: function(container) {
			if (! container) {
				$F.err('elite.chart - clear', 'Clearing chart-box failed')
			}
			if (container.highcharts()) {
				container.highcharts({series:[]});
			}
		},

		/**
		 * 导出mockdata
		 *
		 * @method clear
		 * @param container {$obj} 容器
		 */
		exportMockdata: function() {
			if(! ctlChartData)
				return $F.alert('当前控件无MockData');
			//去掉chart.options对象中为空对象的对象
			var options = ctlChartData.chartTemp.curSelectedUserOption,
				checkEmptyObj = function(option){
					$.each(option, function(i, v){
						if(typeof(v) == 'object'){
							if(JSON.stringify(v) == '{}')
								delete option[i];
							else 
								checkEmptyObj(v);
						}
					});
				};
			checkEmptyObj(options);
			var chartObj = {
				chart_guid: ctlChartData.libGuid,
				sqlListData: ctlChartData.value,
				model: ctlChartData.chartProps,
				chartTemp: ctlChartData.chartTemp
			};
			saveAs(new Blob([JSON.stringify(chartObj)], {
				type : "application/json;charset=UTF-8"
			}),  ctlChartData.chartTemp.chartName + '(' + ctlChartData.libGuid + ').json');
		},

		drawMock: function(container, url){
			$.ajax({
				type: 'get',
				url: url,
				dataType: 'json',
				async: false
			}).done(function(msg) {
				if(! msg)
					return $F.alert('数据有误');
					container.highcharts(msg.chartTemp.curSelectedUserOption);
			});
		},
		
        /**
		 * <p>
		 * @description: 绘制Echart，需要根据chart_id来拼接options(不带数据的部分与数据部分做拼接，数据部分可能又另做函数处理)
		 * </p>
		 *
		 * @param $container: 图表容器
		 * @param chart_name:
		 * @param user_option:
		 * @param user_function:
		 * @param drawChart_data:
		 */
		drawEchart: function($container, chart_name, user_option, user_function, drawChart_data, model_data, model_type, refreshFlag){
			$F.log('elite.chart - draw', 'execute drawEchart');
			if (! (drawChart_data instanceof Array && drawChart_data.length > 0)) {
				$F.err('elite.chart', '动态页面传入数据有误');
			}
			
			// 添加标题、副标题
			if (user_option.title) {
				user_option.title.text = model_data.title || '';
				user_option.title.subtext = model_data.subtitle || '';
			}
			var options = echartOptProcess(chart_name, user_option, user_function, drawChart_data, model_data, model_type, refreshFlag);
            $F.log('elite.chart - draw', '最终的echarts图表脚本', options);

			var echartsInstance;
			if (! echarts.getInstanceByDom($container[0])) {
				// 基于准备好的dom，初始化echarts实例
				echarts.init($container[0]);
			}
	        // 使用刚指定的配置项和数据显示图表。
			echartsInstance = echarts.getInstanceByDom($container[0]);

			// 添加下钻的相应事件
			if (['drilldown_china_province_effect_scatter_map'].indexOf(chart_name) > -1) {
				var handleEvents = null;
				if (!refreshFlag) {
					handleEvents = echartsInstance.handleEvents = new EchartDrillHandleEvents(echartsInstance, options, drawChart_data, model_data);
					
					// 添加事件
					echartsInstance.off('click');
					echartsInstance.on('click', function(params) {
						if (params.name && Object.keys(cityMap_china).filter(item => item.match(params.name)).length > 0 && params.name !== handleEvents.name[handleEvents.idx]) {
							handleEvents.resetOption(params.name);
						}
					});
				
					echartsInstance.setMap = function(mapName) {
						if (mapName.indexOf('市') < 0) mapName = mapName + '市';
						handleEvents.resetOption(mapName);
					};
					
					echartsInstance.setOption(options);
				} else {
					handleEvents = echartsInstance.handleEvents;
					handleEvents.resetOption(handleEvents.name[handleEvents.idx]);
				}
			} else {
				// 绘制图表内容
				echartsInstance.off('click');
				echartsInstance.setOption(options);
			}

			// 添加自适应(通过一个奇技淫巧 是否有滚动条, 如此一来就不用jquery的一直定时监控resize了)
			$container.parent()[0].__resizeListeners__ = [];
			addResizeListener($container.parent()[0], function() {
				echartsInstance.resize();
			});
			
			if (Math.abs($container.width() - $container.children().eq(0).width()) >= 5 
					|| Math.abs($container.height() - $container.children().eq(0).height()) >= 5) {
				echartsInstance.resize();
			}
			
			return echartsInstance;
		},
		
		/**
		 * 绘制highchart
		 * 
		 * @param $container: 图表容器
		 * @param chart_name:
		 * @param user_option:
		 * @param user_function:
		 * @param drawChart_data:
		 */
		drawHighchart: function($container, chartName, curSelectedUserOption, dataType, sqlDataField, model, userFunction, updateFlag) {
			$F.log('elite.chart - drawHighchart', 'execute drawHighchart');
            parseObj(curSelectedUserOption.title, curSelectedUserOption, "title").text = model.title;
            parseObj(curSelectedUserOption.subtitle, curSelectedUserOption, "subtitle").text = model.subtitle;

            highchartOptProcess(curSelectedUserOption, dataType, sqlDataField, model, updateFlag);

            if (userFunction && (userFunction instanceof Array) && userFunction.length > 0) {
            	$.each(userFunction, function(i,tempFunction) {
            		var pArr = $.extend([], tempFunction.params, true);
            		pArr.push($container);
					pArr.unshift(curSelectedUserOption);
					curSelectedUserOption = $XChartsSelfFN['HighCharts'][chartName][tempFunction.name].fn.apply(null, pArr);
            	});
            }
            if(chartName && chartName.startWith('h_funnel_')){
            	if(curSelectedUserOption.series[0].data){
            		$.each(curSelectedUserOption.series[0].data, function(i, v){
            			v[1] = v[1] + 0.1;
            		});
            	}
            	if(curSelectedUserOption.tooltip){
            		curSelectedUserOption.tooltip.formatter = function() { 
            			var s = '<span style="color:{series.color}">\u25CF</span> '+this.point.name+': <b>'+ (this.point.y - 0.1) +'</b><br/>' ; 
            			return s;
            		};
            	}
            }
            if (updateFlag) {
            	var chartObj = $container.highcharts();
            	if(chartObj){
            		var xAxis= chartObj.xAxis[0];
            		var series_before = chartObj.series;
            		var axis_categories = parseObj(curSelectedUserOption.xAxis, curSelectedUserOption, "xAxis").categories;
    				var seriesList = curSelectedUserOption.series;
                    if((!xAxis.categories || (xAxis.categories && xAxis.categories.length == axis_categories.length)) && series_before.length==seriesList.length){
                    	if(xAxis.categories && xAxis.categories.length) xAxis.setCategories(axis_categories);
    					$.each(series_before,function(i,v){
    		    			v.update({name:seriesList[i].name});
    		    			v.update({data:seriesList[i].data});
    		    	    });
    					
    					// 更新数据时发现 图表 w/h、 容器 w/h 之差 有5px的时候   调用reflow()去 适应容器大小  
    					// 2017-6-12 11:15:26 sher --> steel 呼叫中心
    					if (Math.abs($container.width() - $container.children().eq(0).width()) >= 5 
                                || Math.abs($container.height() - $container.children().eq(0).height()) >= 5) {
							chartObj.reflow();
						}
    					
                    } else {
                    	$container.highcharts(curSelectedUserOption);
                    }
            	} else {
            		$container.highcharts(curSelectedUserOption);
            	}
            } else {
            	if ($E.debug) {
            		$F.log('elite.chart - drawHighchart', '最终的Hightcharts图表脚本', curSelectedUserOption);
            	}
            	console.log(curSelectedUserOption)
            	$container.highcharts(curSelectedUserOption);
            	
            	// fixed 动态页面画组件时flex布局 先画了图表的容器(这时图表也跟着画)， 
                // 然后再画flex布局的另一半容器， 先画的图表就会比真实的容器大
                $container.parent()[0].__resizeListeners__ = [];
				addResizeListener($container.parent()[0], function() {
					$container.highcharts() && $container.highcharts().reflow();
					$container.parent()[0].__resizeListeners__ = [];
				});
            }
			return $container.highcharts();
		}
    };
	
	/**
	 * 判断是否是管理台编辑图表 默认为true
	 */
	
	var managerDebug = true;
	
	/*
	 * 当前chart控件数据
	 * */
	var ctlChartData = undefined;

	/**
	 * echart-中国及省名
	 */
	var cityMap_china = {"北京市":["北京"],"天津市":["天津"],"河北省":["石家庄","唐山","秦皇岛","邯郸","邢台","保定","张家口","承德","沧州","廊坊","衡水","省直辖县级行政区划"],"山西省":["太原","大同","阳泉","长治","晋城","朔州","晋中","运城","忻州","临汾","吕梁"],"内蒙古自治区":["呼和浩特","包头","乌海","赤峰","通辽","鄂尔多斯","呼伦贝尔","巴彦淖尔","乌兰察布","兴安盟","锡林郭勒盟","阿拉善盟"],"辽宁省":["沈阳","大连","鞍山","抚顺","本溪","丹东","锦州","营口","阜新","辽阳","盘锦","铁岭","朝阳","葫芦岛"],"吉林省":["长春","吉林","四平","辽源","通化","白山","松原","白城","延边朝鲜族自治州"],"黑龙江省":["哈尔滨","齐齐哈尔","鸡西","鹤岗","双鸭山","大庆","伊春","佳木斯","七台河","牡丹江","黑河","绥化","大兴安岭地区"],"上海市":["上海"],"江苏省":["南京","无锡","徐州","常州","苏州","南通","连云港","淮安","盐城","扬州","镇江","泰州","宿迁"],"浙江省":["杭州","宁波","温州","嘉兴","湖州","绍兴","金华","衢州","舟山","台州","丽水"],"安徽省":["合肥","芜湖","蚌埠","淮南","马鞍山","淮北","铜陵","安庆","黄山","滁州","阜阳","宿州","六安","亳州","池州","宣城"],"福建省":["福州","厦门","莆田","三明","泉州","漳州","南平","龙岩","宁德"],"江西省":["南昌","景德镇","萍乡","九江","新余","鹰潭","赣州","吉安","宜春","抚州","上饶"],"山东省":["济南","青岛","淄博","枣庄","东营","烟台","潍坊","济宁","泰安","威海","日照","莱芜","临沂","德州","聊城","滨州","菏泽"],"河南省":["郑州","开封","洛阳","平顶山","安阳","鹤壁","新乡","焦作","濮阳","许昌","漯河","三门峡","南阳","商丘","信阳","周口","驻马店","省直辖县级行政区划"],"湖北省":["武汉","黄石","十堰","宜昌","襄阳","鄂州","荆门","孝感","荆州","黄冈","咸宁","随州","恩施土家族苗族自治州","省直辖县级行政区划"],"湖南省":["长沙","株洲","湘潭","衡阳","邵阳","岳阳","常德","张家界","益阳","郴州","永州","怀化","娄底","湘西土家族苗族自治州"],"广东省":["广州","韶关","深圳","珠海","汕头","佛山","江门","湛江","茂名","肇庆","惠州","梅州","汕尾","河源","阳江","清远","东莞","中山","潮州","揭阳","云浮"],"广西壮族自治区":["南宁","柳州","桂林","梧州","北海","防城港","钦州","贵港","玉林","百色","贺州","河池","来宾","崇左"],"海南省":["海口","三亚","三沙","儋州","省直辖县级行政区划"],"重庆市":["重庆"],"四川省":["成都","自贡","攀枝花","泸州","德阳","绵阳","广元","遂宁","内江","乐山","南充","眉山","宜宾","广安","达州","雅安","巴中","资阳","阿坝藏族羌族自治州","甘孜藏族自治州","凉山彝族自治州"],"贵州省":["贵阳","六盘水","遵义","安顺","毕节","铜仁","黔西南布依族苗族自治州","黔东南苗族侗族自治州","黔南布依族苗族自治州"],"云南省":["昆明","曲靖","玉溪","保山","昭通","丽江","普洱","临沧","楚雄彝族自治州","红河哈尼族彝族自治州","文山壮族苗族自治州","西双版纳傣族自治州","大理白族自治州","德宏傣族景颇族自治州","怒江傈僳族自治州","迪庆藏族自治州"],"西藏自治区":["拉萨","日喀则","昌都","林芝","山南","那曲地区","阿里地区"],"陕西省":["西安","铜川","宝鸡","咸阳","渭南","延安","汉中","榆林","安康","商洛"],"甘肃省":["兰州","嘉峪关","金昌","白银","天水","武威","张掖","平凉","酒泉","庆阳","定西","陇南","临夏回族自治州","甘南藏族自治州"],"青海省":["西宁","海东","海北藏族自治州","黄南藏族自治州","海南藏族自治州","果洛藏族自治州","玉树藏族自治州","海西蒙古族藏族自治州"],"宁夏回族自治区":["银川","石嘴山","吴忠","固原","中卫"],"新疆维吾尔自治区":["乌鲁木齐","克拉玛依","吐鲁番","哈密","昌吉回族自治州","博尔塔拉蒙古自治州","巴音郭楞蒙古自治州","阿克苏地区","克孜勒苏柯尔克孜自治州","喀什地区","和田地区","伊犁哈萨克自治州","塔城地区","阿勒泰地区","自治区直辖县级行政区划"],"台湾省":[],"香港特别行政区":[],"澳门特别行政区":[]};
	
	/**
	 * echarts-中国地图经纬度
	 */
    var geoCoordMap_china = { '海门':[121.15,31.89], '鄂尔多斯':[109.781327,39.608266], '招远':[120.38,37.35], '舟山':[122.207216,29.985295], '齐齐哈尔':[123.97,47.33], '盐城':[120.13,33.38], '赤峰':[118.87,42.28], '青岛':[120.33,36.07], '乳山':[121.52,36.89], '金昌':[102.188043,38.520089], '泉州':[118.58,24.93], '莱西':[120.53,36.86], '日照':[119.46,35.42], '胶南':[119.97,35.88], '南通':[121.05,32.08], '拉萨':[91.11,29.97], '云浮':[112.02,22.93], '梅州':[116.1,24.55], '文登':[122.05,37.2], '上海':[121.48,31.22], '攀枝花':[101.718637,26.582347], '威海':[122.1,37.5], '承德':[117.93,40.97], '厦门':[118.1,24.46], '汕尾':[115.375279,22.786211], '潮州':[116.63,23.68], '丹东':[124.37,40.13], '太仓':[121.1,31.45], '曲靖':[103.79,25.51], '烟台':[121.39,37.52], '福州':[119.3,26.08], '瓦房店':[121.979603,39.627114], '即墨':[120.45,36.38], '抚顺':[123.97,41.97], '玉溪':[102.52,24.35], '张家口':[114.87,40.82], '阳泉':[113.57,37.85], '莱州':[119.942327,37.177017], '湖州':[120.1,30.86], '汕头':[116.69,23.39], '昆山':[120.95,31.39], '宁波':[121.56,29.86], '湛江':[110.359377,21.270708], '揭阳':[116.35,23.55], '荣成':[122.41,37.16], '连云港':[119.16,34.59], '葫芦岛':[120.836932,40.711052], '常熟':[120.74,31.64], '东莞':[113.75,23.04], '河源':[114.68,23.73], '淮安':[119.15,33.5], '泰州':[119.9,32.49], '南宁':[108.33,22.84], '营口':[122.18,40.65], '惠州':[114.4,23.09], '江阴':[120.26,31.91], '蓬莱':[120.75,37.8], '韶关':[113.62,24.84], '嘉峪关':[98.289152,39.77313], '广州':[113.23,23.16], '延安':[109.47,36.6], '太原':[112.53,37.87], '清远':[113.01,23.7], '中山':[113.38,22.52], '昆明':[102.73,25.04], '寿光':[118.73,36.86], '盘锦':[122.070714,41.119997], '长治':[113.08,36.18], '深圳':[114.07,22.62], '珠海':[113.52,22.3], '宿迁':[118.3,33.96], '咸阳':[108.72,34.36], '铜川':[109.11,35.09], '平度':[119.97,36.77], '佛山':[113.11,23.05], '海口':[110.35,20.02], '江门':[113.06,22.61], '章丘':[117.53,36.72], '肇庆':[112.44,23.05], '大连':[121.62,38.92], '临汾':[111.5,36.08], '吴江':[120.63,31.16], '石嘴山':[106.39,39.04], '沈阳':[123.38,41.8], '苏州':[120.62,31.32], '茂名':[110.88,21.68], '嘉兴':[120.76,30.77], '长春':[125.35,43.88], '胶州':[120.03336,36.264622], '银川':[106.27,38.47], '张家港':[120.555821,31.875428], '三门峡':[111.19,34.76], '锦州':[121.15,41.13], '南昌':[115.89,28.68], '柳州':[109.4,24.33], '三亚':[109.511909,18.252847], '自贡':[104.778442,29.33903], '吉林':[126.57,43.87], '阳江':[111.95,21.85], '泸州':[105.39,28.91], '西宁':[101.74,36.56], '宜宾':[104.56,29.77], '呼和浩特':[111.65,40.82], '成都':[104.06,30.67], '大同':[113.3,40.12], '镇江':[119.44,32.2], '桂林':[110.28,25.29], '张家界':[110.479191,29.117096], '宜兴':[119.82,31.36], '北海':[109.12,21.49], '西安':[108.95,34.27], '金坛':[119.56,31.74], '东营':[118.49,37.46], '牡丹江':[129.58,44.6], '遵义':[106.9,27.7], '绍兴':[120.58,30.01], '扬州':[119.42,32.39], '常州':[119.95,31.79], '潍坊':[119.1,36.62], '重庆':[106.54,29.59], '台州':[121.420757,28.656386], '南京':[118.78,32.04], '滨州':[118.03,37.36], '贵阳':[106.71,26.57], '无锡':[120.29,31.59], '本溪':[123.73,41.3], '克拉玛依':[84.77,45.59], '渭南':[109.5,34.52], '马鞍山':[118.48,31.56], '宝鸡':[107.15,34.38], '焦作':[113.21,35.24], '句容':[119.16,31.95], '北京':[116.46,39.92], '徐州':[117.2,34.26], '衡水':[115.72,37.72], '包头':[110,40.58], '绵阳':[104.73,31.48], '乌鲁木齐':[87.68,43.77], '枣庄':[117.57,34.86], '杭州':[120.19,30.26], '淄博':[118.05,36.78], '鞍山':[122.85,41.12], '溧阳':[119.48,31.43], '库尔勒':[86.06,41.68], '安阳':[114.35,36.1], '开封':[114.35,34.79], '济南':[117,36.65], '德阳':[104.37,31.13], '温州':[120.65,28.01], '九江':[115.97,29.71], '邯郸':[114.47,36.6], '临安':[119.72,30.23], '兰州':[103.73,36.03], '沧州':[116.83,38.33], '临沂':[118.35,35.05], '南充':[106.110698,30.837793], '天津':[117.2,39.13], '富阳':[119.95,30.07], '泰安':[117.13,36.18], '诸暨':[120.23,29.71], '郑州':[113.65,34.76], '哈尔滨':[126.63,45.75], '聊城':[115.97,36.45], '芜湖':[118.38,31.33], '唐山':[118.02,39.63], '平顶山':[113.29,33.75], '邢台':[114.48,37.05], '德州':[116.29,37.45], '济宁':[116.59,35.38], '荆州':[112.239741,30.335165], '宜昌':[111.3,30.7], '义乌':[120.06,29.32], '丽水':[119.92,28.45], '洛阳':[112.44,34.7], '秦皇岛':[119.57,39.95], '株洲':[113.16,27.83], '石家庄':[114.48,38.03], '莱芜':[117.67,36.19], '常德':[111.69,29.05], '保定':[115.48,38.85], '湘潭':[112.91,27.87], '金华':[119.64,29.12], '岳阳':[113.09,29.37], '长沙':[113,28.21], '衢州':[118.88,28.97], '廊坊':[116.7,39.53], '菏泽':[115.480656,35.23375], '合肥':[117.27,31.86], '武汉':[114.31,30.52], '大庆':[125.03,46.58] };
	
	/**
	 * 地图下钻处理
	 */
	var EchartDrillHandleEvents = function(chartInstance, options, drawChart_data, model_data) {
		var a = this;
		this.chart = chartInstance;
		this.options = options;
		this.dwData = drawChart_data;
		this.modeData = model_data;

		// 层级索引
		this.name = ['中国'];
		this.idx = 0;
		this.pos = { leftPlus: 115, leftCur: 150, left: 198, top: 50 };
		this.line = [[0, 0], [8, 11], [0, 22]];
		// style
		this.style = {
			font: '18px "Microsoft YaHei", sans-serif',
			textColor: '#eee',
			lineColor: 'rgba(147, 235, 248, .8)'
		};

		options.series[0].data = a.initSeriesData(a.dwData);
		options.graphic = [{
            type: 'group',
            left: a.pos.left,
            top: a.pos.top - 4,
            children: [{
                type: 'line',
                left: 0,
                top: -20,
                shape: {
                    x1: 0,
                    y1: 0,
                    x2: 60,
                    y2: 0
                },
                style: {
                    stroke: a.style.lineColor,
                }
            }, {
                type: 'line',
                left: 0,
                top: 20,
                shape: {
                    x1: 0,
                    y1: 0,
                    x2: 60,
                    y2: 0
                },
                style: {
                    stroke: a.style.lineColor,
                }
            }]
        }, 
        {
            id: a.name[a.idx],
            type: 'group',
            left: a.pos.left + 2,
            top: a.pos.top,
            children: [{
                type: 'polyline',
                left: 90,
                top: -12,
                shape: {
                    points: a.line
                },
                style: {
                    stroke: 'transparent',
                    key: name[0]
                },
                onclick: function() {
                    var name = a.style.key;
                    a.resetOption(name);
                }
            }, {
                type: 'text',
                left: 0,
                top: 'middle',
                style: {
                    text: '中国',
                    textAlign: 'center',
                    fill: a.style.textColor,
                    font: a.style.font
                },
                onclick: function() {
                    a.resetOption('中国');
                }
            }, {
                type: 'text',
                left: 0,
                top: 10,
                style: {
                    text: 'China',
                    textAlign: 'center',
                    fill: a.style.textColor,
                    font: '12px "Microsoft YaHei", sans-serif',
                },
                onclick: function() {
                    a.resetOption('中国');
                }
            }]
        }];
	};

	EchartDrillHandleEvents.prototype = {
        
        resetOption: function(selectedName) {
        	var a = this;
			var chartInstance = this.chart;
			var options = this.options;
			var dwData = this.dwData;
			var modeData = this.modeData;
			var name = this.name;
			var pos = this.pos;

            var breadcrumb = this.createBreadcrumb(selectedName);
            var j = name.indexOf(selectedName);
            var l = options.graphic.length;
            if (j < 0) {
                options.graphic.push(breadcrumb);
                options.graphic[0].children[0].shape.x2 = 145;
                options.graphic[0].children[1].shape.x2 = 145;
                if (options.graphic.length > 2) {
                    var cityData = [];
                    var likeCityInProvince = Object.keys(cityMap_china).filter(item => item.match(selectedName))
                    if (likeCityInProvince.length > 0) {
                        var cityInProvince = cityMap_china[likeCityInProvince[0]];
                        for (var y = 0; y < cityInProvince.length; y++) {
                            for (var x = 0; x < dwData.length; x++) {
                                if(dwData[x][modeData.city_index].match(cityInProvince[y])){
                                    cityData.push(dwData[x]);
                                }
                            }
                        }
                    }
                    
                    if(cityData.length > 0){
                        options.series[0].data = a.initSeriesData(cityData);
                    } else {
                        options.series[0].data = [];
                    }
                }
                name.push(selectedName);
                a.idx++;
            } else {
                options.graphic.splice(j + 2, l);
                if (options.graphic.length <= 2) {
                    options.graphic[0].children[0].shape.x2 = 60;
                    options.graphic[0].children[1].shape.x2 = 60;
                    options.series[0].data = a.initSeriesData(a.dwData);
                }	
                name.splice(j + 1, l);
                a.idx = j;
                pos.leftCur -= pos.leftPlus * (l - j - 1);
            }

            options.geo.map = selectedName;
            options.geo.zoom = 0.4;
			chartInstance.clear();
            chartInstance.setOption(options);
            this.zoomAnimation();
        },

        /**
         * name 地图名
         **/
        createBreadcrumb: function(name) {
			var a = this;
			var pos = this.pos;
			var style = this.style;
			var line = this.line;
			
            var cityToPinyin = { '中国': 'zhongguo', '上海': 'shanghai', '河北': 'hebei', '山西': 'shangxi', '内蒙古': 'neimenggu', '辽宁': 'liaoning', '吉林': 'jilin', '黑龙江': 'heilongjiang', '江苏': 'jiangsu', '浙江': 'zhejiang', '安徽': 'anhui', '福建': 'fujian', '江西': 'jiangxi', '山东': 'shangdong', '河南': 'henan', '湖北': 'hubei', '湖南': 'hunan', '广东': 'guangdong', '广西': 'guangxi', '海南': 'hainan', '四川': 'sichuan', '贵州': 'guizhou', '云南': 'yunnan', '西藏': 'xizang', '陕西': 'shanxi', '甘肃': 'gansu', '青海': 'qinghai', '宁夏': 'ningxia', '新疆': 'xinjiang', '北京': 'beijing', '天津': 'tianjin', '重庆': 'chongqing', '香港': 'xianggang', '澳门': 'aomen' };
            var breadcrumb = {
                type: 'group',
                id: name,
                left: pos.leftCur + pos.leftPlus,
                top: pos.top + 3,
                children: [
					{
						type: 'polyline',
						left: -90,
						top: -5,
						shape: {
							points: line
						},
						style: {
							stroke: '#fff',
							key: name
							// lineWidth: 2,
						},
						onclick: function() {
							var name = style.key;
							a.resetOption(name);
						}
					}, 
					{
						type: 'text',
						left: -68,
						top: 'middle',
						style: {
							text: name,
							textAlign: 'center',
							fill: style.textColor,
							font: style.font
						},
						onclick: function() {
							var name = style.text;
							a.resetOption(name);
						}
					}, 
					{
						type: 'text',
						left: -68,
						top: 10,
						style: {
							name: name,
							text: cityToPinyin[name] ? cityToPinyin[name].toUpperCase() : '',
							textAlign: 'center',
							fill: style.textColor,
							font: '12px "Microsoft YaHei", sans-serif',
						},
						onclick: function() {
							var name = this.style.name;
							a.resetOption(name);
						}
					}
				]
            }
            pos.leftCur += pos.leftPlus;
            return breadcrumb;
        },

       	/**
		 * 设置effectscatter
		 */
        initSeriesData: function(data) {
			var modeData = this.modeData;
            var temp = [];
            for (var i = 0; i < data.length; i++) {
                var geoCoord = geoCoordMap_china[data[i][modeData.city_index]];
                if (geoCoord) {
                    temp.push({
                        name: data[i][modeData.city_index],
                        value: geoCoord.concat(data[i][modeData.value_index]),
                    });
                }
            };
            return temp;
        },

        zoomAnimation: function() {
        	var a = this;
            var count = null;
            var zoom = function(per) {
                if (!count) count = per;
                count = count + per;
                a.chart.setOption({
                    geo: { zoom: count }
                });
                if (count < 1) window.requestAnimationFrame(function() { zoom(0.2); });
            };
            window.requestAnimationFrame(function() { zoom(0.2); });
        }
    };
	
    /**
     * 适应project的EliteChart
     */
    var EliteChart = function(project) {
    	this.project = project;
		this.charts = {};
    };
	EliteChart.prototype = {
		/*
		 * 画报表图表
		 */
		drawRptChart: function(excelPos, allChart, $container){
			for(var chartField in allChart){  //这里可能有多个chart (一般只会有一个)
				var chartObj = allChart[chartField];
				$F.dataService('SystemDo2', {
					data: $F.sqlbean('ChartDesign.ChartLib.findByRptChartId', this.project.token, [chartObj.chartType]),
					digest: this.project.digest,
					success: function(data){
						if (data.code > 0) {
							var count = data.value[0].count;
							if (count > 0) {
								var userOption = data.value[0].fields[count - 1][0];
								userOption = eval('({' + userOption + '})');
								var allSub = chartObj.charSubInfo.allSub,
									xlXValue = allSub[0].xlXValue,
                                    seriesArr = [];
								var xLXValueArr = disposeData(xlXValue.split(':'), chartObj.vRCFlag, excelPos);
								console.log(xLXValueArr);
								if(!xLXValueArr)
									alert('获取x轴数据有误');
								userOption.xAxis.categories = xLXValueArr;
								$.each(allSub,  function(i, subTemp){
									var seriesObj = {};
									seriesObj.name = subTemp.xlName;
									seriesObj.data = disposeData(subTemp.xlValue.split(':'), chartObj.vRCFlag, excelPos);
									if(subTemp.xlVisFlag){
										parseObj(seriesObj.dataLabels,seriesObj,'dataLabels').enabled = true;
									}
									seriesArr.push(seriesObj);
								});
								if(chartObj.chartType == 5 && xLXValueArr.length > 0){  //如果是饼图  对数据进行二次处理
									var pieData = [],
										data = seriesArr[0].data;
									for(var i = 0 ; i < xLXValueArr.length; i++){
										var tempArr = [xLXValueArr[i], data[i]];
										pieData.push(tempArr);
									}
									seriesArr[0].data = pieData
								};
								console.log(seriesArr);
								userOption.series = seriesArr;
								if(chartObj.nameToChart){
									userOption.title.text = chartObj.chartName;
								}
								if(chartObj.xName){
									userOption.xAxis.title.text = chartObj.xName;
								}
								if(chartObj.yName){
									userOption.yAxis.title.text = chartObj.yName;
								}
								$container.css({'height':'500px','width':'500px','margin-top':'30px'}).highcharts(userOption);
							}else{
								return $F.alert('无此条记录');
							}
							console.log('loadChartTypes successed');
						} else {
							return $F.alert(data.message);
						}
					}
				});
			}
		},
		
		refresh: function($container, chart_guid, sqlListData, model){
			$F.log('elite.chart - refresh', '刷新图表');
			managerDebug = false;
			var a = this, chartTemp;
			chartTemp = a.charts[chart_guid];
			if (chartTemp) {
				if(chartTemp.fromSource == 1){
					return $EliteChart.drawHighchart($container, chartTemp, chartName, chartTemp.curSelectedUserOption, 
						chartTemp.dataType, sqlListData, model,chartTemp.userFunction, true);
				} else {
					//a.drawEchart();
				}
			} else {
				// return a.draw2($container, chart_guid, sqlListData, model);
			}
		},
		
		/**
		 * 根据提供的参数 画出图表
		 * @param ctlChart 图表控件的实例对象
		 * ctlChart: {
		 *     box, 				// -> $container 图表容器
		 *     objProp.chartType, 	// -> chart_guid 需要画出来的图表guid
		 *     value,				// -> sqldData sql查询出来的systemdo2类型数据
		 *     chartProps			// -> model 图表数据model
		 * }
		 */
		draw: function(ctlChart, callback) {
			$F.log('elite.chart - draw', '开始绘制图表 - ↓');
			managerDebug = false;
			//chart_guid = ctlChart.libGuid, 
			var a = this;
			var $container = ctlChart.box;
			var chart_guid = ctlChart.libGuid;
			var sqlListData = ctlChart.value;
			var model = ctlChart.chartProps;
			chart_guid = (chart_guid? chart_guid : ctlChart.objProp.chartType);  //兼容20170927版本
			ctlChartData = ctlChart;
			$container.off('dblclick').on('dblclick', function(e){
				if(e.ctrlKey){
					$EliteChart.exportMockdata();
				}
			});
			$F.log('elite.chart - draw', '绘制数据:[' + sqlListData + ']', '绘制数据模型对应关系:[' + JSON.stringify(model) + ']');
			if (a.charts[chart_guid]) { // 有缓存过该chart_lib_user的数据
				var chartTemp = a.charts[chart_guid];
				// 比对版本号(即modifieddate) 以此判断缓存的chart_lib_user的数据是否有变化 
				$F.dataService('SystemDo2', {
					data: $F.sqlbean("Chart.Query.findVersionByGuid", a.project.token, [chart_guid]),
					digest: a.project.digest,
					success: function(data){
						if (data.code > 0) {
							if (data.value[0].count > 0) {
								var v = data.value[0].fields[0];
								if (chartTemp.modifiedDate == v[0]) { // 版本号一致  说明admin端没有更改数据
									if (chartTemp.fromSource == 1) {
										if($container.highcharts()) {
                                            ctlChartData.chartTemp = chartTemp;
											ctlChart.chart = $EliteChart.drawHighchart($container, chartTemp.chartName, chartTemp.curSelectedUserOption, 
												chartTemp.dataType, sqlListData, model, chartTemp.userFunction, true);
											$.isFunction(callback) && callback();
											$F.log('elite.chart - draw', '完成绘制图表- ↑');
										} else {
											return a.draw2(ctlChart, callback);
										}
									} else {
										var chart = ctlChart.chart = $EliteChart.drawEchart($container, chartTemp.chartName, chartTemp.curSelectedUserOption, 
											chartTemp.userFunction, sqlListData, model, chartTemp.dataType, true);
										if (chart && $.isFunction(ctlChart.clickCallback)) {
											chart.off('click');
											chart.on('click', function(params) {
												var obj = { NAME: params.name };
												if (params.value) obj.value = params.value[2];
												ctlChart.clickCallback(null, obj);
											});
										}
										$.isFunction(callback) && callback();
										$F.log('elite.chart - draw', '完成绘制图表- ↑');
									}
								} else { // 版本号不一致, 从新请求数据并缓存
									a.draw2(ctlChart, callback);
								}
							}
						} else {
							$F.alert(data.message);
						}
					}
				});
			} else { // 未缓存
				a.draw2(ctlChart, callback);
			}
		},

		draw2: function(ctlChart, callback){
			var a = this;
			var token = a.project.token;
			var $container = ctlChart.box; 
			var chart_guid = ctlChart.libGuid; 
			var sqlListData = ctlChart.value;
			var model = ctlChart.chartProps;
			chart_guid = (chart_guid? chart_guid : ctlChart.objProp.chartType);
			$F.dataService('SystemDo2', {
				data: $F.sqlbean('Chart.Query.findByGuid', token, [chart_guid]),
				digest: a.project.digest,
				success: function(data){
					//console.log("Chart.Query.findByGuid: ", JSON.stringify(data));
					if (data.code > 0) {
						if (data.value[0].count > 0) {
							var curSelectedUserOption;
							var userChartTemp = data.value[0].fields[0];
							var userFunction = userChartTemp[1];
							var chartId = userChartTemp[2];
							var chartName = userChartTemp[3];
							var dataType = userChartTemp[4];
							var fromSource = userChartTemp[5];
							var modifiedDate = userChartTemp[6];
							userFunction = userFunction ? JSON.parse(userFunction) : [];

							if (fromSource == 1) {
                            	try {
									curSelectedUserOption = eval('(' + userChartTemp[0] + ')');	
								} catch (e) {
									try {
										curSelectedUserOption = eval('({' + userChartTemp[0] + '})');	
									} catch (e) {
										return $F.alert('请检查自定义对象是否有误！');
									}
								}
								ctlChart.chartType = 'highchart';
								ctlChart.chart = $EliteChart.drawHighchart($container, chartName,curSelectedUserOption, dataType, sqlListData, model, userFunction);
								if(ctlChart.seriesEvents){
                                    ctlChart.setSeriesEvents(ctlChart.seriesEvents);
								}
                            } else {
								try {
									curSelectedUserOption = eval('(' + userChartTemp[0] + ')');	
								} catch (e) {
									return $F.alert('请检查自定义对象是否有误！');
								}
								ctlChart.chartType = 'echart';
								var chart = ctlChart.chart = $EliteChart.drawEchart($container, chartName, curSelectedUserOption, userFunction, sqlListData, model, dataType);
								if (chart && $.isFunction(ctlChart.clickCallback)) {
									chart.off('click');
									chart.on('click', function(params) {
										var obj = { NAME: params.name };
										if (params.value) obj.value = params.value[2];
										ctlChart.clickCallback(null, obj);
									});
								}
                            }
                            var chartTemp = {
                                chartId: chartId,
								chartName: chartName,
								dataType: dataType,
								curSelectedUserOption : curSelectedUserOption,
								userFunction: userFunction,
								fromSource: fromSource,
								modifiedDate: modifiedDate
                            };
                            ctlChartData.chartTemp = chartTemp;
                            a.charts[chart_guid] = chartTemp;
                            $.isFunction(callback) && callback();
						} else {
							$F.err('elite.chart', '数据接口异常，未获取条记录');
						}
					} else {
						return $F.alert(data.message);
					}
				},
				always: function() {
					$F.log('elite.chart - draw', '完成绘制图表 - ↑');
				}
			});
		}
	};
	
    /**
     * echart之options的处理过程
     */
    function echartOptProcess(chart_name, options, user_function, drawChart_data, model_data, model_type, refreshFlag) {                
        var AxisData = [], seriesName = [], seriesData = [],
            hasSelfFN = (user_function && (user_function instanceof Array && user_function.length > 0)) ? true : false,
            defaultUFParas = [options, drawChart_data, model_data];
		
		switch (model_type) {

            // 【饼图之  南丁格尔玫瑰图】   rose_pie || e_rose_pie_XX
            case 11:
                $.each(drawChart_data, function(i, dwData) {
                    var _seriesData = {};
                    _seriesData = {
                        name: dwData[model_data.label_index],
                        value: dwData[model_data.value_index]
                    };
                    if (model_data.color_index >= 0 && dwData[model_data.color_index]) {
                        _seriesData.itemStyle = { normal: {color: dwData[model_data.color_index]} };
                    }
                    seriesName.push(dwData[model_data.label_index]);
                    seriesData.push(_seriesData);
                });
                
                // 设置series的data数据
                if (options.series instanceof Array) {
                    options.series[0].data = seriesData;    
                } else {
                    options.series.data = seriesData;
                }
                // 设置legend标签数据
                options.legend.data = seriesName;
        
                break;
            
            //【仪表盘】之 单个仪表盘   single_gauge || e_single_gauge_XX
            case 12:
				if (drawChart_data.length > 0) {
					seriesData.push({
						name: drawChart_data[0][model_data.name_index],
						value: drawChart_data[0][model_data.value_index]
					});
				} else {
					// 保护没有值时不变成 NAN%
					seriesData.push({
						name: '',
						value: 0
					});
				}
                // 设置series的data数据
                if (options.series instanceof Array) {
                    options.series[0].data = seriesData;    
                } else {
                    options.series.data = seriesData;
                }
                break;

            //【气泡图 (普通气泡 + 特效气泡)】    scatter_effectscatter_map || e_scatter_effectscatter_map_XX
            case 13:
                // 设置 legend - formatter
                if (hasSelfFN) {
                    $.each(user_function, function(i,tempFN){
                        var fnParams = defaultUFParas.concat(tempFN.params);
                        //curSelectedUserOption = $XChartsSelfFN['ECharts'][chart_name][tempFN.name].apply(null, fnParams);
                    });
                }
                
                // 设置series的name、data数据
                for (var i = 0; i < options.series.length; i++) {
                    var _series = options.series[i];
                    var isTopSeries = ((i + 1) == options.series.length);
                    if (isTopSeries) {
                    	if (!model_data.top_name) {
                    		// _series.name = '';
                    		$F.log('elite.chart - draw', '没有给top数据组别明值(这组数据应该叫什么名字)');
                    	} else {
                    		_series.name = model_data.top_name;
                    	}
                    } else {
                    	if (!model_data.common_name) {
                    		// _series.name = '';
                    		$F.log('elite.chart - draw', '没有给普通数据组别明值(这组数据应该叫什么名字)');
                    	} else {
                            _series.name = model_data.common_name;
                    	}
                    }
                    _series.data = convertScatterEffectScatterMapData(drawChart_data, model_data, isTopSeries);
                }
                break;
                
            // 【气泡图】nscatter_map(普通气泡) ||  neffectScatter_map(特效气泡) || e_nscatter_map_XX || e_neffectscatter_map_XX
            case 14:
                // 设置 legend - formatter
                if (hasSelfFN) {
                    $.each(user_function, function(i,tempFunction){
                        var params = $.extend([], tempFunction.params, true);
                        params.unshift(drawChart_data);
                        params.unshift(options);
                        //curSelectedUserOption = $XChartsSelfFN['ECharts'][chart_name][tempFunction.name].apply(null, params);
                    });
                }
                
                // 设置series的data数据
                var seriesMapArr = converScatterOrEffectScatterMapData(drawChart_data, model_data);
                for (var i = 0; i < options.series.length; i++) {
                    var _series = options.series[i];
                    _series.name =  seriesMapArr[i].name;
                    _series.data =  seriesMapArr[i].value;
                }
                break;
                
            // 【中国省级地图-单/多series】china_province_map || n_china_province_map
            case 15:
                
                if (chart_name == 'china_province_map') { // 中国省级地图-单series
                	// 设置自定义函数
                    var maxData = 0, name = '中国', mapType = options.series[0].mapType;
            		if (mapType == 'china' || mapType == '中国') {
            			name = '中国';
            		} else if (mapType == 'heinan' || mapType == '河南') {
            			name = '河南省';
            		} else {
            			return $F.err('elite.chart - echartOptProcess', 'mapType: [' + mapType + ']', 'mapType 错误');
            		}
                	seriesName = [];
                	seriesData = [];
                	$.each(drawChart_data, function(i, dwData) {
                		if (dwData[model_data.series_index] == name) {
	                		var data = dwData[model_data.value_index];
	                		if (data > maxData) {
	                			maxData = data;
	                		}
	                		seriesData.push({
	                			name: dwData[model_data.label_index],
	                			value: data
	                		});
                		}
                	});
                	// 设置series的data数据
                    options.series[0].data = seriesData;
                	// 设置visualMap.max
                	if (options.visualMap) {
                		options.visualMap.max = maxData;
                	}                    
                    // 设置legend标签数据
                    if (options.legend) {
                    	options.legend.data = seriesName;
                    }
                } else if (chart_name == 'n_china_province_map') { // 中国省级地图-多series
                	// 设置自定义函数
                    var seriesMap = converCommonMapData(drawChart_data, model_data, options);
                    var series0 = options.series[0];
                    seriesName = [];
                    options.series = [];
                    
                    // 设置series的data数据
                    $.each(seriesMap, function(name, data) {
                    	seriesName.push(name);
                    	options.series.push($.extend({}, series0, { name: name, data: data }, true));
                    });
                    // 设置legend标签数据
                    if (options.legend) {
                    	options.legend.data = seriesName;
                    }
                }
				break;
				
			case 16:
				var seriesDataArr = [], indicatorName = [], indicatorMax = [];
				$.each(drawChart_data, function(i, dwData) {
					var serseriesIndex = seriesName.indexOf(dwData[model_data.series_index]);
					var indicatorIndex = indicatorName.indexOf(dwData[model_data.label_index]);

					if (serseriesIndex == -1) {
						seriesName.push(dwData[model_data.series_index]);
						serseriesIndex = seriesName.length - 1;
						seriesDataArr[serseriesIndex] = [];
					}
					seriesDataArr[serseriesIndex].push(dwData[model_data.value_index]);

					if (indicatorIndex == -1) {
						indicatorName.push(dwData[model_data.label_index]);
						indicatorIndex = indicatorName.length - 1;
					}
					indicatorMax[indicatorIndex] = dwData[model_data.maxvalue_index];
				});
				
				// 设置legend标签数据
				options.legend.data = seriesName;
				// 设置radar.indicator
				options.radar = options.radar || {};
				options.radar.indicator = [];
				$.each(indicatorName, function(i, name) {
					options.radar.indicator.push({ name: name, max: indicatorMax[i] || 0 })
				});
				
				// 设置series的data数据]
				options.series = options.series || [];
				options.series[0] = { type: 'radar', data: [] };
                $.each(seriesName, function(i, name){
					options.series[0].data.push({ name: name, value: seriesDataArr[i] });
				});
				break;
				
			case 17:
				// 设置 legend - formatter
                if (hasSelfFN) {
                    $.each(user_function, function(i, tempFunction){
						
                    });
                }
                
                // 设置series的data数据
				for (var i = 0; i < options.series.length; i++) {
					var _series = options.series[i];
					if (i < options.series.length - 1) {
						_series.data = convertScatterEffectScatterMapData(drawChart_data, model_data, false);
					} else {
						_series.renderItem = bMapRenderItem(drawChart_data, model_data);
					}
                }
				break;
				
			case 18:
				// 设置 legend - formatter
                if (hasSelfFN) {
                    $.each(user_function, function(i, tempFunction){});
                }
                
                // 设置series的data数据
				for (var i = 0; i < options.series.length; i++) {
					var _series = options.series[i];
					_series.data = convertScatterEffectScatterMapData(drawChart_data, model_data, false);
                }
                break;
                
			case 19:
                // 设置 legend - formatter
                if (hasSelfFN) {
                    $.each(user_function, function(i,tempFN){});
                }
                
                // 设置series的name、data数据
                for (var i = 0; i < options.series.length; i++) {
                	var _series = options.series[i];
                	if (i < options.series.length - 1) {
                		var isTopSeries = ((i + 1) == (options.series.length - 1));
                        if (isTopSeries) {
                        	if (!model_data.top_name) {
                        		//_series.name = '';
                        		$F.log('elite.chart - draw', '没有给top数据组别明值(这组数据应该叫什么名字)');
                        	} else {
                        		_series.name = model_data.top_name;
                        	}
                        } else {
                        	if (!model_data.common_name) {
                        		_series.name = '';
                        		$F.log('elite.chart - draw', '没有给普通数据组别明值(这组数据应该叫什么名字)');
                        	} else {
                                _series.name = model_data.common_name;
                        	}
                        }
                        _series.data = convertScatterEffectScatterMapData(drawChart_data, model_data, isTopSeries);
					} else {
						_series.renderItem = bMapRenderItem(drawChart_data, model_data);
					}
                }
                break;

            default: 
            	$F.err('elite.chart - echartOptProcess', chart_name + ': has not matched model_type');
		};

        $F.log('elite.chart - echartOptProcess', chart_name + '-AxisData: ', AxisData);
        $F.log('elite.chart - echartOptProcess', chart_name + '-seriesName: ', seriesName);
        $F.log('elite.chart - echartOptProcess', chart_name + '-seriesData: ', seriesData);
        return options;
    }

    /**
     * hightchart之 options的处理过程
     */
    function highchartOptProcess(curSelectedUserOption, dataType, sqlDataField, model, updateFlag) {
        var errorMsg = "";

        switch (dataType) {
            case 1:
                parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption, "yAxis").title, curSelectedUserOption.yAxis, "title").text = model.yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption, "yAxis").labels, curSelectedUserOption.yAxis,"labels").format = '{value}' +  (model.yAxis_labels_format ? model.yAxis_labels_format : "");
                var crossMappingIndex = judgeDataIndex(sqlDataField, model.cross_index,'非法的交叉列索引',0,true);   //parseInt(model.cross_index);
                if (isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var xAxleMappingIndex = judgeDataIndex(sqlDataField, model.xAxis_data_index, '非法的x轴数据列索引', 0, true);   //parseInt(model.xAxis_data_index);
                if (isNaN(xAxleMappingIndex)) return $F.alert(xAxleMappingIndex); 
                var DataMappingIndex = judgeDataIndex(sqlDataField, model.data_index, '非法的数据列索引', 0);    //parseInt(model.data_index);
                if (isNaN(DataMappingIndex)) return $F.alert(DataMappingIndex); 
                
                errorMsg = judgeDataIndex(sqlDataField,DataMappingIndex,'数据项数据有误',1);
                if (errorMsg) return alert(errorMsg); 
                sqlDataField = getNewChartData(sqlDataField, xAxleMappingIndex, crossMappingIndex, DataMappingIndex);
                modelDataDeal(curSelectedUserOption, sqlDataField, xAxleMappingIndex, crossMappingIndex, DataMappingIndex, '', dataType, '', false, updateFlag);
                break;
            case 2:
                parseObj(parseObj(curSelectedUserOption.xAxis,curSelectedUserOption,"xAxis").title,curSelectedUserOption.yAxis,"title").text = model.left_xAxis_title;
                parseObj(parseObj(curSelectedUserOption.xAxis,curSelectedUserOption, "xAxis").labels,curSelectedUserOption.xAxis,"labels").format = '{value}' +  (model.left_xAxis_labels_format?model.left_xAxis_labels_format:"");
                parseObj(parseObj(curSelectedUserOption.yAxis,curSelectedUserOption,"yAxis").title,curSelectedUserOption.yAxis,"title").text = model.yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis,curSelectedUserOption,"yAxis").labels,curSelectedUserOption.yAxis,"labels").format = '{value}' +  (model.right_yAxis_labels_format ? model.right_yAxis_labels_format : "");
                var crossMappingIndex = judgeDataIndex(sqlDataField ,model.cross_index, '非法的交叉列索引', 0, true); 
                if (isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var splineInventedXDataIndex = judgeDataIndex(sqlDataField, model.xAxis_data_index, '非法的x轴数据列索引', 0);
                if (isNaN(splineInventedXDataIndex)) return $F.alert(splineInventedXDataIndex); 
                errorMsg = judgeDataIndex(sqlDataField, splineInventedXDataIndex, 'x轴数据列数据有误', 1);
                if (errorMsg) return alert(errorMsg); 
                var splineInventedYDataIndex = judgeDataIndex(sqlDataField,model.yAxis_data_index,'非法的y轴数据列索引', 0);
                if (isNaN(splineInventedYDataIndex)) return $F.alert(splineInventedYDataIndex); 
                errorMsg = judgeDataIndex(sqlDataField, splineInventedYDataIndex, 'y轴数据列数据有误', 1);
                if (errorMsg) return alert(errorMsg); 
                
                modelDataDeal(curSelectedUserOption, sqlDataField, -1, crossMappingIndex, splineInventedXDataIndex, splineInventedYDataIndex, dataType, '', false, updateFlag);
                break;
            case 3:
                var crossMappingIndex = judgeDataIndex(sqlDataField, model.cross_index, '非法的交叉列索引', 0, true);   //parseInt(model.cross_index);
                if (isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var sort_Index = judgeDataIndex(sqlDataField, model.sort_index, '非法的标签列索引', 0);
                if(isNaN(sort_Index)) return $F.alert(sort_Index); 
                var sort_data_Index = judgeDataIndex(sqlDataField, model.sort_data_index, '非法的标签列数据索引', 0);
                if (isNaN(sort_data_Index)) return $F.alert(sort_data_Index); 
                errorMsg = judgeDataIndex(sqlDataField, sort_data_Index, '标签列数据有误', 1);
                if (errorMsg) return alert(errorMsg); 
                var prominentDataUnit = model.prominent_data_unit, unitArr;
                if (prominentDataUnit) {
                    unitArr = prominentDataUnit.split(',');
                }
                modelDataDeal(curSelectedUserOption, sqlDataField,-1, crossMappingIndex, sort_Index,sort_data_Index, dataType, unitArr, false, updateFlag);
                break;
            case 4:
                parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption, "yAxis").title, curSelectedUserOption.yAxis, "title").text = model.yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption,"yAxis").labels, curSelectedUserOption.yAxis, "labels").format = '{value}' +  (model.yAxis_labels_format ? model.yAxis_labels_format : "");
                var crossMappingIndex = judgeDataIndex(sqlDataField, model.cross_index, '非法的交叉列索引', 0, true); 
                if (isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var xAxleMappingIndex = judgeDataIndex(sqlDataField, model.xAxis_data_index, '非法的x轴数据列索引', 0, true); 
                if (isNaN(xAxleMappingIndex)) return $F.alert(xAxleMappingIndex); 
                var areaBeginIndex = judgeDataIndex(sqlDataField, model.start_range_data_index, '非法的开始范围数据列索引', 0); 
                if (isNaN(areaBeginIndex)) return $F.alert(areaBeginIndex); 
                errorMsg = judgeDataIndex(sqlDataField,areaBeginIndex,'开始范围数据项有误',1);
                if (errorMsg) return $F.alert(errorMsg); 
                
                var areaEndIndex = judgeDataIndex(sqlDataField, model.end_range_data_index, '结束范围数据项有误', 0); 
                if (isNaN(areaEndIndex)) return $F.alert(areaEndIndex); 
                errorMsg = judgeDataIndex(sqlDataField,areaEndIndex,'开始范围数据项有误',1);
                if (errorMsg) return $F.alert(errorMsg); 
                modelDataDeal(curSelectedUserOption, sqlDataField, xAxleMappingIndex, crossMappingIndex, areaBeginIndex, areaEndIndex, dataType, '', false, updateFlag);
                break;
            case 5:
                parseObj(parseObj(curSelectedUserOption.yAxis,curSelectedUserOption,"yAxis").title,curSelectedUserOption.yAxis,"title").text = model.yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis,curSelectedUserOption,"yAxis").labels,curSelectedUserOption.yAxis,"labels").format = '{value}' +  (model.yAxis_labels_format ? model.yAxis_labels_format : "");
                if((model.data_min && !isNaN(parseInt(model.data_min))) || parseInt(model.data_min) == 0){
                    parseObj(curSelectedUserOption.yAxis).min = parseInt(model.data_min);
                }
                if(model.data_max && !isNaN(parseInt(model.data_max))){
                    parseObj(curSelectedUserOption.yAxis).max = parseInt(model.data_max);
                }
                var crossMappingIndex = judgeDataIndex(sqlDataField,model.cross_index,'非法的交叉列索引',0,true); 
                if(isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var DataMappingIndex = judgeDataIndex(sqlDataField,model.data_index,'非法的数据列索引',0);    //parseInt(model.data_index);
                if(isNaN(DataMappingIndex)) return $F.alert(DataMappingIndex); 
                errorMsg = judgeDataIndex(sqlDataField,DataMappingIndex,'数据项数据有误',1);
                if(errorMsg) return alert(errorMsg); 
                modelDataDeal(curSelectedUserOption, sqlDataField, -1, crossMappingIndex, DataMappingIndex, '', dataType, '', false, updateFlag);
                break;
            case 6:
                parseObj(parseObj(curSelectedUserOption.yAxis[0],curSelectedUserOption, "yAxis").title,curSelectedUserOption.yAxis[0], "title").text = model.left_yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis[0],curSelectedUserOption, "yAxis").labels,curSelectedUserOption.yAxis[0], "labels").format = '{value}' +  (model.left_yAxis_labels_format ? model.left_yAxis_labels_format : "");
                parseObj(parseObj(curSelectedUserOption.yAxis[1],curSelectedUserOption, "yAxis").title,curSelectedUserOption.yAxis[1], "title").text = model.right_yAxis_title;
                parseObj(parseObj(curSelectedUserOption.yAxis[1],curSelectedUserOption, "yAxis").labels,curSelectedUserOption.yAxis[1], "labels").format = '{value}' + (model.right_yAxis_labels_format ? model.right_yAxis_labels_format : "");
                var crossMappingIndex = judgeDataIndex(sqlDataField,model.cross_index, '非法的交叉列索引',0,true);   //parseInt(model.cross_index);
                if(isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var xAxleMappingIndex = judgeDataIndex(sqlDataField,model.xAxis_data_index, '非法的x轴数据列索引', 0, true);   //parseInt(model.xAxis_data_index);
                if(isNaN(xAxleMappingIndex)) return $F.alert(xAxleMappingIndex); 
                var DataMappingIndex = judgeDataIndex(sqlDataField,model.data_index, '非法的数据列索引', 0);    //parseInt(model.data_index);
                if(isNaN(DataMappingIndex)) return $F.alert(DataMappingIndex); 
                
                errorMsg = judgeDataIndex(sqlDataField,DataMappingIndex,'数据项数据有误',1);
                if(errorMsg) return alert(errorMsg); 
                var lineColumnCrossName = model.line_cross_name;
                modelDataDeal(curSelectedUserOption, sqlDataField, xAxleMappingIndex, crossMappingIndex,DataMappingIndex, 0, dataType, lineColumnCrossName, false, updateFlag);
                break;
            case 7:
                var crossMappingIndex = judgeDataIndex(sqlDataField,model.cross_index,'非法的交叉列索引',0,true);   //parseInt(model.cross_index);
                if(isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex); 
                var sort_Index = judgeDataIndex(sqlDataField,model.sort_index,'非法的标签列索引',0);
                if(isNaN(sort_Index)) return $F.alert(sort_Index); 
                var sort_data_Index = judgeDataIndex(sqlDataField,model.sort_data_index,'非法的标签列数据索引',0);
                if(isNaN(sort_data_Index)) return $F.alert(sort_data_Index); 
                errorMsg = judgeDataIndex(sqlDataField, sort_data_Index, '标签列数据有误', 1);
                if(errorMsg) return alert(errorMsg); 
                modelDataDeal(curSelectedUserOption, sqlDataField, -1, crossMappingIndex, sort_Index, sort_data_Index, dataType, model, false, updateFlag);
                break;
			case 8:
				parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption, "yAxis").title, curSelectedUserOption.yAxis, "title").text = model.yAxis_title;
				parseObj(parseObj(curSelectedUserOption.yAxis, curSelectedUserOption, "yAxis").labels, curSelectedUserOption.yAxis,"labels").format = '{value}' +  (model.yAxis_labels_format ? model.yAxis_labels_format : "");
				var crossMappingIndex = judgeDataIndex(sqlDataField, model.cross_index, '非法的交叉列索引', 0, true);   //parseInt(model.cross_index);
				if (isNaN(crossMappingIndex)) return $F.alert(crossMappingIndex);
				var xAxleMappingIndex = judgeDataIndex(sqlDataField, model.xAxis_data_index, '非法的x轴数据列索引', 0, true);   //parseInt(model.xAxis_data_index);
				if (isNaN(xAxleMappingIndex)) return $F.alert(xAxleMappingIndex);
				var stackIndex = judgeDataIndex(sqlDataField, model.stack_index, '非法的分组列索引', 0, true);
				if (isNaN(stackIndex)) return $F.alert(stackIndex);

				var DataMappingIndex = judgeDataIndex(sqlDataField, model.data_index, '非法的数据列索引', 0);    //parseInt(model.data_index);
				if (isNaN(DataMappingIndex)) return $F.alert(DataMappingIndex);
				errorMsg = judgeDataIndex(sqlDataField,DataMappingIndex,'数据项数据有误',1);
				if (errorMsg) return alert(errorMsg);
				var doubleAxisCrossName = model.doubleAxisCrossName;
				modelDataDeal(curSelectedUserOption, sqlDataField, xAxleMappingIndex, crossMappingIndex, DataMappingIndex, stackIndex, dataType, doubleAxisCrossName, false, updateFlag);
				break;
            case 9:
                var sort_Index = judgeDataIndex(sqlDataField, model.sort_index, '非法的标签列索引', 0);
                if(isNaN(sort_Index)) return $F.alert(sort_Index);
                var sort_data_Index = judgeDataIndex(sqlDataField, model.sort_data_index, '非法的数据列索引', 0);
                if (isNaN(sort_data_Index)) return $F.alert(sort_data_Index);
                errorMsg = judgeDataIndex(sqlDataField, sort_data_Index, '标签列数据有误', 1);
                if (errorMsg) return alert(errorMsg);
                modelDataDeal(curSelectedUserOption, sqlDataField, -1, -1, sort_Index,sort_data_Index, dataType, null, true, updateFlag);
                break;
            default:
                $F.alert('模板 [' + dataType + '] 类型不存在');
        }
    }

	function parseObj(obj, curObj, label){
    	if (obj){
    		return obj;
    	} else {
    		if (curObj && label){
    			curObj[label] = {};
        		return curObj[label];
    		}
    	}
    }
    
    /**
     * 判断动态页面输入数据是否正常
     */
	function judgeDataIndex(sqlDataField, param, errorMsg, dataType, flag){
		if (dataType == 0) {
			if (!(parseInt(param) >= 0)) {
				if (!flag) {
					return errorMsg;
				} else {
					return -1;
				}
			} else {
            	return parseInt(param);
            }
		} else if (dataType == 1) {
        	if(sqlDataField[0]){
    			if (isNaN(sqlDataField[0][param])) {
    				 return errorMsg;
    			}
			}
        }
    }
	
	function getNewChartData(oldChartData, axisIndex, crossIndex, dataIndex) {
        var crossArr = [], xAxisArr = [], newChartData = [];
        if (oldChartData && oldChartData.length > 0) {
            $.each(oldChartData, function (i, v) {
                if ($.inArray(v[crossIndex], crossArr) == -1) crossArr.push(v[crossIndex]);
            });
            $.each(oldChartData, function (i, v) {
                if ($.inArray(v[axisIndex], xAxisArr) == -1) {
                    xAxisArr.push(v[axisIndex]);
                    $.each(crossArr, function (j, z) {
                        var dataTemp = [];
                        if (z == v[crossIndex]) {
                            dataTemp = v;
                        } else {
                            dataTemp[axisIndex] = v[axisIndex];
                            dataTemp[crossIndex] = z;
                            dataTemp[dataIndex] = 0;
                        }
                        newChartData.push(dataTemp);
                    });
                } else {
                    $.each(newChartData, function (j, z) {
                        if (z[axisIndex] == v[axisIndex] && z[crossIndex] == v[crossIndex]) {
                            z[dataIndex] = v[dataIndex];
                            return false;
                        }
                    });
                }
            });
        }
        return newChartData;
    }

	/**
	 * 获取中国 市对应的 坐标。 (ep: 上海(市) => [经纬度二维数组])
	 */
    function matchCoordinateOfChina(cityName) {
		var keyName = Object.keys(geoCoordMap_china).find(function(name, index) {
			return cityName.match(new RegExp(name, 'gi'));
		});
        return keyName ? geoCoordMap_china[keyName] : '';
	}

    /**
     * 获取地图点数据
     */
    function convertScatterEffectScatterMapData(dwDatas, model_data, isTopSeries) {
    	var dwDatas = dwDatas;
    	var seriesData = [];
    	if (isTopSeries && model_data.top_n > 0) {
    		var topN = model_data.top_n || dwDatas.length;
    		dwDatas = dwDatas.sort(function(a, b) {
    			return b[model_data.value_index] - a[model_data.value_index];
    		}).slice(0, topN);
    	}
    	
    	$.each(dwDatas, function(i, dwData) {
			var geoCoord = matchCoordinateOfChina(dwData[model_data.city_index]);
			if (! geoCoord) {
				return true;
            }
			seriesData.push({
				name: dwData[model_data.city_index],
				value: geoCoord.concat(dwData[model_data.value_index])
			});
		});
    	return seriesData;
    }
    
    function converScatterOrEffectScatterMapData(dwDatas, model_data) {
    	var dwDatas = dwDatas, seriesMapArr = [];
    	$.each(dwDatas, function(i, dwData) {
    		var index = dwData[model_data.series_order_index];
    		
    		if (! seriesMapArr[index]) {
    			seriesMapArr[index] = {
    				name: dwData[model_data.series_name_index],
    				value: []
    			}
    		}
    		var geoCoord = matchCoordinateOfChina(dwData[model_data.city_index]);
			if (! geoCoord) {
				return true;
            }
			seriesMapArr[index].value.push({
				name: dwData[model_data.city_index],
				value: geoCoord.concat(dwData[model_data.value_index])
			});
    	});
    	return seriesMapArr;
    }
    
    /**
     * 通用的获取legend & series的data  and 数据的最大值
     */
    function converCommonMapData(dwDatas, model_data, options) {
    	var dwDatas = dwDatas, maxData = 0, seriesMap = {};
    	$.each(dwDatas, function(i, dwData) {
    		if (!seriesMap[dwData[model_data.series_index]]) {
    			seriesMap[dwData[model_data.series_index]] = [];
    		}
    		var data = dwData[model_data.value_index];
    		if (data > maxData) {
    			maxData = data;
    		}
    		seriesMap[dwData[model_data.series_index]].push({
    			name: dwData[model_data.label_index],
    			value: data
    		});
    	});
    	if (options.visualMap) {
    		options.visualMap.max = maxData;
    	}
    	return seriesMap;
    }
    
    /**
     * 设置地图区域点
     */
    function bMapRenderItem(dwDatas, model_data) {
		return function(params, api) {
			var coords = [];
			var coordsSorted = [];
			var points = [];
			
			$.each(dwDatas, function(i, dwData) {
				if (dwData[model_data.polygon_index] == 1) {
					coords.push(matchCoordinateOfChina(dwData[model_data.city_index]));
				}
			});
			coords.sort(function(x, y) { return y[1] - x[1]});
			
			if (coords && coords.length > 0) {
				// 寻找最高点
				var topPoint = coords[0];
				coordsSorted.push(topPoint);
				
				// 最高点x轴左边点
				var leftBesises = coords.filter(function(coord) { return coord[0] < topPoint[0] });
				leftBesises.sort(function(x, y) {
				  if (x[1] == y[1]) {
					return y[0] - x[0];
				  } else{
					return y[1] - x[1]
				  }
				});
				leftBesises.map(function(coord) { coordsSorted.push(coord); });

				// 同x轴的点， 只取地图最下面的点
				var centerBesises = coords.filter(function(coord) { return coord[0] == topPoint[0] });
				centerBesises.sort(function(x, y) { return x[1] - y[2]});
				if (centerBesises.length > 1) {
					coordsSorted.push(centerBesises[0]);
				}
				
				// 最高点x轴右边点
				var rightBesises = coords.filter(function(coord) { return coord[0] > topPoint[0] });
				rightBesises.sort(function(x, y) {
				  if (x[1] == y[1]) {
					return x[0] - y[0];
				  } else {
					return x[1] - y[2];
				  }
				});
				rightBesises.map(function(coord) { coordsSorted.push(coord); });
				
				for (var i = 0; i < coordsSorted.length; i++) {
					points.push(api.coord(coordsSorted[i]));
				}
			}
			
			var color = api.visual('color');
	
			return {
				type: 'polygon',
				shape: {
					points: echarts.graphic.clipPointsByRect(points, {
						x: params.coordSys.x,
						y: params.coordSys.y,
						width: params.coordSys.width,
						height: params.coordSys.height
					})
				},
				style: api.style({
					fill: color,
					stroke: echarts.color.lift(color)
				})
			};
		}
	}
    
    function _getDefaultOption(opts) {
		var a = this, url = './chartLib/' + opts.XChart + '/' + opts.chart_name + '.txt?r' + Math.random();

		Ajax.post({
			url: url,
			dataType : "text",
			async: opts.async,
			success: function(msg) {
				if (opts.success) {
					opts.success(msg);
				}
			},
			error: function($xhr, ts, err) {
				if (opts.error) {
					opts.error($xhr, ts, err);
				}
			}
		});
	}
	
    function disposeData(objArr, vRCFlag, excelPos){
       var int2col = function(col) {
            var res = "";
            var codeA = "A".charCodeAt();
            while (col > 0) {
                col--;
                res = String.fromCharCode(codeA + col % 26) + res;
                col = parseInt(col / 26);
            }
            return res;
        };
        var maxRow = 0, bodyStart = 0, headRow = 0;
        $.each(excelPos, function(i, v){
            if(v.data.subtable && v.data.subtable.end ){
                maxRow = v.data.subtable.end;
                bodyStart = v.data.subtable.bodyStart;
                headRow = v.data.subtable.headRow;
                return false;
            }
        });
        var xLvalueBegin =objArr[0], xLvalueEnd = objArr[1];
        var beginRowIndex, beginColIndex, endRowIndex, endColIndex;
        if(xLvalueBegin && xLvalueEnd){
            beginRowIndex = xLvalueBegin.indexOf('R') + 1;
            beginColIndex = xLvalueBegin.indexOf('C');
            endRowIndex = xLvalueEnd.indexOf('R') + 1;
            endColIndex = xLvalueEnd.indexOf('C');
        }else {
            return alert('入参格式有误');
        }
        if(xLvalueBegin.indexOf('RNEND') > -1){
            beginRowIndex = maxRow;
        }else {
            beginRowIndex = parseInt(xLvalueBegin.substring(beginRowIndex, beginColIndex));
        }

        if(xLvalueBegin.indexOf('CNEND') > -1){
            beginColIndex = true;
        }else {
            beginColIndex = parseInt(xLvalueBegin.substring(beginColIndex+1));
        }

        if(xLvalueEnd.indexOf('RNEND') > -1){
            endRowIndex = maxRow;
        }else {
            endRowIndex = parseInt(xLvalueEnd.substring(endRowIndex, endColIndex));
        }

        if(xLvalueEnd.indexOf('CNEND') > -1){
            endColIndex = 35;
        }else {
            endColIndex = parseInt(xLvalueEnd.substring(endColIndex+1));
        }
        var dataArr = [];
        if(vRCFlag == '1'){ //根据列取值
            var colName = int2col(beginColIndex);
            $.each(excelPos, function(i, v){
                var p = /[A-Z]/g, letterLength = 0;for(var d = 0;d < i.length; d++){ if(p.test(i.substr(d,1))){ letterLength ++; } }
                var colNamePos = i.substring(0, letterLength),
                    colIndex = i.substring(letterLength),
                    subTable = v.data.subtable,
                    real = v.data.real;
                if(colName == colNamePos){
                    if(subTable && subTable.bodyStart && subTable.bodyStart < colIndex && colIndex <= (subTable.bodyEnd + 1) )
                        dataArr.push(real);
                }
            });
            return dataArr.splice(beginRowIndex + headRow - bodyStart - 1, endRowIndex - bodyStart);
        }else { //根据行取值
            $.each(excelPos, function(i, v){
                var p = /[A-Z]/g, letterLength = 0;for(var d = 0;d < i.length; d++){ if(p.test(i.substr(d,1))){ letterLength ++; } }
                var row = parseInt(i.substring(letterLength, i.length));
                if(row == beginRowIndex){
                    var subTable = v.data.subtable,
                        real = v.data.real;
                    if(subTable)
                        dataArr.push(real);
                }
            });
            return dataArr;
        }
    }

    function dispenseType(type, seriesJsonTemp, curCrossName, DataValue, seriesDataArrTemp, stringfield1, dataIndex1, dataIndex2, drilldownSeriesArr, i, xAxleMappingIndex){
        if (type == 1 || type == 5) {
			seriesDataArrTemp.push(DataValue[dataIndex1]);
        }else if (type == 2) {
            var tempArr = [];
            tempArr.push(DataValue[dataIndex1]);
            tempArr.push(DataValue[dataIndex2]);
            seriesDataArrTemp.push(tempArr);
        } else if (type == 3) {
            var tempObj = {}; 
            $.each(stringfield1,function(i,v){
                if(DataValue[dataIndex1] == v){
                    tempObj.name = DataValue[dataIndex1];
                    tempObj.y = DataValue[dataIndex2];
                    tempObj.sliced = true;
                    tempObj.selected = true;
                    seriesDataArrTemp.push(tempObj);
                    return false;
                }
            });
            if (!tempObj.name) {
                var tempArr = [];
                tempArr.push(DataValue[dataIndex1]);
                tempArr.push(DataValue[dataIndex2]);
                seriesDataArrTemp.push(tempArr);
            }
        } else if (type == 4) {
            var tempArr = [];
            tempArr.push(DataValue[xAxleMappingIndex]);
            tempArr.push(DataValue[dataIndex1]);
            tempArr.push(DataValue[dataIndex2]);
            seriesDataArrTemp.push(tempArr);
        } else if (type == 6) {
            seriesDataArrTemp.push(DataValue[dataIndex1]);
            if (curCrossName && stringfield1) {
            	var arr = stringfield1.split('|');
				var flag = true;
				$.each(arr, function(g, stringfield) {
					if (stringfield == curCrossName) {
						seriesJsonTemp.type = "line";
						seriesJsonTemp.yAxis = 1;
						seriesJsonTemp.dataLabels = {enabled: true};
						flag = false;
						return false
					}
				});
				if (flag && seriesJsonTemp.type != 'bar')
					seriesJsonTemp.type = "column"
            } else
                seriesJsonTemp.type = "column";
        } else if (type == 7) {
            var dataTempObj = {}, drilldownSerieObj = {};
            dataTempObj.name = DataValue[dataIndex1];
            dataTempObj.y = DataValue[dataIndex2];
            dataTempObj.drilldown = DataValue[dataIndex1];
            seriesDataArrTemp.push(dataTempObj);
            if(managerDebug){
                drilldownSeriesArr.push($XChartsMockData['HighCharts']['drilldown_pie']['drilldownData'][i]);
            } else {
                var drilldownTableName = stringfield1.drilldown_tableName;
                var drilldownWhereName = stringfield1.drilldown_whereName;
                var drilldownKeyColumn = stringfield1.drilldown_keyColumn;
                var drilldownValueColumn = stringfield1.drilldown_valueColumn
                if(drilldownTableName || drilldownWhereName ){
                    $F.dataService('SystemDo2', {
                        async: false,
                        data: $F.sqlbean(
                            'Chart.query.drillDown', 
                            this.project.token, 
                            [drilldownKeyColumn, drilldownValueColumn, drilldownTableName, '', drilldownWhereName, DataValue[dataIndex1]]
                        ),
                        digest: this.project.digest,
                        success: function(data){
                            console.log("Chart.query.drillDown: ", JSON.stringify(data));
                            var serieObjTemp = {};
                            if (data.code > 0) {
                                if (data.value[0].count > 0) {
                                    var fields = data.value[0].fields, fieldTempArr = [], key, value;
                                    serieObjTemp.name = DataValue[dataIndex1];
                                    serieObjTemp.id = DataValue[dataIndex1];
                                    $.each(fields, function(i,v){
                                        var seriedateArr = [];
                                        key = v[0];value = 1;
                                        //value = v[drilldownValueColumn];
                                        seriedateArr.push(key);
                                        seriedateArr.push(value);
                                        fieldTempArr.push(seriedateArr);
                                    });
                                    serieObjTemp.data = fieldTempArr;
                                    drilldownSeriesArr.push(serieObjTemp);
                                } else {
                                    console.log('无此条记录');
                                }
                            } else {
                                return $F.alert(data.message);
                            }
                        }
                    });
                }
            }
        } else if(type == 8){
			seriesDataArrTemp.push(DataValue[dataIndex1]);
			seriesJsonTemp.stack = DataValue[dataIndex2];
		} else if(type == 9){
			seriesDataArrTemp.push({
                name: DataValue[dataIndex1],
				data: [{y: DataValue[dataIndex2]}]
            });
        }
    }

    function modelDataDeal(curSelectedUserOption, sqlDataField, xAxleMappingIndex, crossMappingIndex, dataIndex1, dataIndex2, type, stringfield1, solidgaugeFlag, updateFlag ) {
        try {
            var xAxis_categoriesArr = [], chartSeries = [], crossColumnArr = [], drilldownObj = {}, drilldownSeriesArr = [];
            if (crossMappingIndex >= 0) {
                $.each(sqlDataField, function (i, value) {
                    if (xAxleMappingIndex >= 0) {
                        if ($.inArray(value[xAxleMappingIndex], xAxis_categoriesArr) == -1) {
                            xAxis_categoriesArr.push(value[xAxleMappingIndex]);
                        }
                    }
                    if ($.inArray(value[crossMappingIndex], crossColumnArr) == -1) {
                        var seriesJsonTemp = {};
                        var seriesDataArrTemp = [];
                        var curCrossName = value[crossMappingIndex];
                        $.each(sqlDataField, function (i, DataValue) {
                            var crossName = DataValue[crossMappingIndex];
                            if (crossName == curCrossName) {
                                dispenseType(type, seriesJsonTemp, curCrossName, DataValue, seriesDataArrTemp, 
                                    stringfield1, dataIndex1, dataIndex2, drilldownSeriesArr, i, xAxleMappingIndex);
                            }
                        });
                        if(drilldownSeriesArr.length > 0){
                            drilldownObj.series = drilldownSeriesArr;
                        }
                        seriesJsonTemp.name = curCrossName;
                        seriesJsonTemp.data = seriesDataArrTemp;
                        chartSeries.push(seriesJsonTemp);
                        crossColumnArr.push(value[crossMappingIndex]);
                    }
                });
            }
            console.log("crossColumnArr:" + crossColumnArr);
            
            if (!(crossMappingIndex >= 0)) {
                var seriesDataArrTemp = [];
                var seriesJsonTemp = {};
                $.each(sqlDataField, function (i, DataValue) {
                    dispenseType(type, seriesJsonTemp, '', DataValue, seriesDataArrTemp, stringfield1, dataIndex1, dataIndex2, drilldownSeriesArr, i);
                });
                if(drilldownSeriesArr.length > 0){
                    drilldownObj.series = drilldownSeriesArr;
                }
                if(solidgaugeFlag){
                    chartSeries = seriesDataArrTemp;
				} else{
					seriesJsonTemp.data = seriesDataArrTemp;
	                chartSeries.push(seriesJsonTemp);
				}
            }
            if(xAxis_categoriesArr.length > 0){
           	// $.extend([], curSelectedUserOption.xAxis);
            	if(curSelectedUserOption.xAxis instanceof Array){
            		curSelectedUserOption.xAxis[0].categories = xAxis_categoriesArr;
            		curSelectedUserOption.xAxis[1].categories = xAxis_categoriesArr;
            	}else {
            		$.extend(curSelectedUserOption.xAxis, {}).categories = xAxis_categoriesArr;
            	}
            }
          
            /*add by dana 2018-12-28
             * 需要将series属性也放出去供工程师改样式
             * */
            if(!updateFlag && curSelectedUserOption.series && curSelectedUserOption.series.length > 0 && chartSeries.length > 0){
            	$.each(curSelectedUserOption.series, function(i, v){
            		if(v.data && v.data instanceof  Array && v.data[0] instanceof Object){
									var temp = $.extend(true, {},v);
									delete temp['data'];
									chartSeries[i] = $.extend(chartSeries[i], temp);
									$.each(v.data, function(j, z){
										if(v.data instanceof Object){
											chartSeries[i].data[j] = $.extend(z, chartSeries[i].data[j]);
										}
									});
						} else {
							chartSeries[i] = $.extend(v, chartSeries[i]);
						}
					})
				}
					curSelectedUserOption.series = chartSeries;
					curSelectedUserOption.drilldown = drilldownObj;
        } catch (e) {
	        console.error(e);
			return $F.alert('数据处理有误');
        }
    }
	
	/*
     * 公共的特殊处理函数
     */
    var publicSelfFN = {
		setXDataLabelColorPublicObj : {
			name: 'x轴上数据需要变颜色的标签：',
			fn: function (opts, xnameArr, color) {
				if(!(opts.xAxis.categories && opts.xAxis.categories.length > 0 && opts.series[0].data && opts.series[0].data.length > 0)){
					return ;
				}
				var xnameList = xnameArr.split(',');
				$.each(xnameList, function(i, xnameTemp) {
					$.each(opts.xAxis.categories, function(j, categorieTemp) {
						if(xnameTemp == categorieTemp){
							var seriesUpdate = [];
							$.each(opts.series, function(z, tempObj) {
								var obj = {};
								obj.y = tempObj.data[j];
								//obj.dataLabels = {};
								parseObj(obj.dataLabels,obj,'dataLabels').color = color;
								tempObj.data[j] = obj;
								seriesUpdate.push(tempObj);
							});
							opts.series = seriesUpdate;
							return false;
						}
					});
				});
				return opts;
			}
		},
		
		/*
		 * set Echarts scatter map tooltip _ real value and percent 
		 */
		setEUF01: function(options, drawChart_data, model_data, label1, label2) {
			var total = 0;
			$.each(drawChart_data, function(i, dwData) {
				total += parseInt(dwData[model_data.value_index]);
			});
			options.tooltip.formatter = function(fmtParams) {
				return fmtParams.seriesName + '<br />' + fmtParams.name + ':'+ label1 + fmtParams.value[2] + 
						label2 + (parseInt(fmtParams.value[2]) / total * 100).toFixed(2) + '%';
			}
		}
		
	};
	
	/** 
	 * 图表option中data数据的 特殊处理函数
	 * 目前不同的chart_lib会有不同的特殊函数
	 */
	window.$XChartsSelfFN = {
		
		//多种图形公共方法--x轴上数据需要变颜色的标签：
		highcharts: {
			/*
			 * 基本折线图 line_basic
			 */
			line_basic : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//基本面积图area_basic
			area_basic : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},


			//面积范围图 bar_basic
			arearange : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//柱状堆叠图 column_placement
			column_placement : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//折线图-柱状图组合--双轴 line_column
			line_column : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//坐标轴反转的曲线图 spline_inverted
			spline_inverted : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//基本柱状图 column_basic
			column_basic : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//基本条形图 bar_basic
			bar_basic : {
				setXDataLabelColor: publicSelfFN.setXDataLabelColorPublicObj
			},

			//环形图 ring_pie
			ring_pie : {
				setDataInsubTitle: {
					name: '将数据组装显示在自行调整的位置，需要调整副标题横纵坐标)',
					fn: function (opts,$container) {
						if(!(opts.series[0].data && opts.series[0].data.length > 0)){
							return ;
						}
						var subtitleText = "", color = opts.colors[0], name = opts.series[0].name,data = opts.series[0].data, 
											labelName=opts.subtitle.text, labelValue1, labelValue2, fontSize = opts.subtitle.style.fontSize;
						if(data[0].name){
							labelValue1 = data[0].y, labelValue2 = data[1].y ;
						}else{
							labelValue1 = data[0][1], labelValue2 = data[1][1] ;	
						}
						var percentValue = ((labelValue1/(labelValue1+labelValue2))*100).toFixed(2)+"%";
						var color = opts.colors[0],color2 = opts.colors[2];
						if(fontSize) {
							subtitleText = '<span style="color:'+color+';fontWeight:bold;font-size:'+(fontSize+2)+'px">'+labelName+'</span><br><br>';
							subtitleText += '&nbsp;&nbsp;<span style="color:'+color+';font-size:'+fontSize+'px">' + (labelValue1+labelValue2) + '</span><br>';
							subtitleText += '<span style="color:'+color+' ;font-size:'+fontSize+'px">' + percentValue + '</span><br>';
						}else {
							subtitleText = '<span style="color:'+color+';fontWeight:bold">'+labelName+'</span><br><br>';
							subtitleText += '&nbsp;&nbsp;<span style="color:'+color+'">' + (labelValue1+labelValue2) + '</span><br>';
							subtitleText += '<span style="color:'+color+'">' + percentValue + '</span><br>';
						}
						
						parseObj(opts.subtitle,opts,'subtitle').text = subtitleText;
						var subTitleY = parseObj(opts.subtitle,opts,'subtitle').y
						if(subTitleY){
							parseObj(opts.subtitle,opts,'subtitle').y = $container.height()/2 + subTitleY;
						}else{
							parseObj(opts.subtitle,opts,'subtitle').y = $container.height()/2;
						}
						
						return opts;
					}
				}
			},

			//漏斗图 ring_pie
			funnel : {

			},

			//实心半圆图 ring_pie
			gauge_solid : {

			},

			//基本饼图 ring_pie
			pie_basic : {

			},

			//基本仪表盘 ring_pie
			gauge_speedometer : {

			}
			
		},
		
		echarts: {
			/* 
			 * 基本柱状图的 数据特殊处理函数
			 */
			basic_bar: {

				// 超过limit就成color色
				setOverColor: {
			    	name: '超过x值显示x色',
					fn: function(opts, labelName, color) {
						var result = [];
						var categories = opts.xAxis.categories;
						var series = opts.series;
						
						$.each(opts, function(i, element) {
							if (element >= limit) {
								var t = {};
								t.value = element;
								t.itemStyle = {normal: {color: color}};
								result.push(t);
							} else {
								result.push(element);
							}
						});
						return result;
					}
				},

			    // 设置最大值时的颜色
				setMaxColor: {
			    	name: '最大值值显示x色',
					fn: function(seriesData, color) {
						var result = [];
						var max = Math.max.apply(null, seriesData)
						$.each(seriesData, function(i, element) {
							if (element == max) {
								var t = {};
								t.value = element;
								t.itemStyle = {normal: {color: color}};
								result.push(t);
							} else {
								result.push(element);
							}
						});
						return result;
					}
			    },

			    // 设置最小值时的颜色
				setMinColor: {
					name: '最小值值显示x色',
					fn: function(seriesData, color) {
						var result = [];
						var min = Math.min.apply(null, seriesData)
						$.each(seriesData, function(i, element) {
							if (element == min) {
								var t = {};
								t.value = element;
								t.itemStyle = {normal: {color: color}};
								result.push(t);
							} else {
								result.push(element);
							}
						});
						return result;
					}
				}
			},
			
			/*
			 * 
			 */
			scatter_effectScatter_map: {
				setEUF01: publicSelfFN.setEUF01
			},
			
			/*
			 * 
			 */
			nScatter_map: {
				setEUF01: publicSelfFN.setEUF01
			},
			
			/*
			 * 
			 */
			nEffectScatter_map: {
				setEUF01: publicSelfFN.setEUF01
			}
		}
	};
	
	
	/*************************** resize plugin start *************************************/
	/**
	 * Detect Element Resize
	 *
	 * https://github.com/sdecima/javascript-detect-element-resize
	 * Sebastian Decima
	 *
	 * version: 0.5.3
	 **/
	var attachEvent = document.attachEvent,
	stylesCreated = false;
	
	if (!attachEvent) {
		var requestFrame = (function(){
			var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
								function(fn){ return window.setTimeout(fn, 20); };
			return function(fn){ return raf(fn); };
		})();
		
		var cancelFrame = (function(){
			var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
								   window.clearTimeout;
		  return function(id){ return cancel(id); };
		})();

		/* Detect CSS Animations support to detect element display/re-attach */
		var animation = false,
			animationstring = 'animation',
			keyframeprefix = '',
			animationstartevent = 'animationstart',
			domPrefixes = 'Webkit Moz O ms'.split(' '),
			startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
			pfx  = '';
		{
			var elm = document.createElement('fakeelement');
			if( elm.style.animationName !== undefined ) { 
				animation = true;
			}    
			
			if( animation === false ) {
				for( var i = 0; i < domPrefixes.length; i++ ) {
					if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
						pfx = domPrefixes[ i ];
						animationstring = pfx + 'Animation';
						keyframeprefix = '-' + pfx.toLowerCase() + '-';
						animationstartevent = startEvents[ i ];
						animation = true;
						break;
					}
				}
			}
			elm = null;
		}
		
		var animationName = 'resizeanim';
		var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
		var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
	}
	
	function checkTriggers(element){
		return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height;
	}
	
	function scrollListener(e) {
		var element = this;
		resetTriggers(this);
		if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
		this.__resizeRAF__ = requestFrame(function(){
			if (checkTriggers(element)) {
				element.__resizeLast__.width = element.offsetWidth;
				element.__resizeLast__.height = element.offsetHeight;
				element.__resizeListeners__.forEach(function(fn){
					fn.call(element, e);
				});
			}
		});
	}
	
	function resetTriggers(element){
		var triggers = element.__resizeTriggers__,
			expand = triggers.firstElementChild,
			contract = triggers.lastElementChild,
			expandChild = expand.firstElementChild;
		contract.scrollLeft = contract.scrollWidth;
		contract.scrollTop = contract.scrollHeight;
		expandChild.style.width = expand.offsetWidth + 1 + 'px';
		expandChild.style.height = expand.offsetHeight + 1 + 'px';
		expand.scrollLeft = expand.scrollWidth;
		expand.scrollTop = expand.scrollHeight;
	}
	
	function createStyles() {
		if (!stylesCreated) {
			//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
			var css = (animationKeyframes ? animationKeyframes : '') +
					'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
					'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
				head = document.head || document.getElementsByTagName('head')[0],
				style = document.createElement('style');
			
			style.type = 'text/css';
			if (style.styleSheet) {
				style.styleSheet.cssText = css;
			} else {
				style.appendChild(document.createTextNode(css));
			}

			head.appendChild(style);
			stylesCreated = true;
		}
	}
	
	var addResizeListener = function(element, fn){
		if (attachEvent) element.attachEvent('onresize', fn);
		else {
			if (!element.__resizeTriggers__) {
				if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
				createStyles();
				element.__resizeLast__ = {};
				element.__resizeListeners__ = [];
				(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
				element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +'<div class="contract-trigger"></div>';
				element.appendChild(element.__resizeTriggers__);
				resetTriggers(element);
				element.addEventListener('scroll', scrollListener, true);
				
				/* Listen for a css animation to detect element display/re-attach */
				animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
					if(e.animationName == animationName)
						resetTriggers(element);
				});
			}
			element.__resizeListeners__.push(fn);
		}
	};
	
	var removeResizeListener = function(element, fn){
		if (attachEvent) element.detachEvent('onresize', fn);
		else {
			element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
			if (!element.__resizeListeners__.length) {
				element.removeEventListener('scroll', scrollListener);
				element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
			}
		}
	};
	/*************************** resize plugin end *************************************/
	
})(jQuery);
